package top.hzy520.user.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import top.hzy520.common.constants.Constants;
import top.hzy520.common.exception.YuyuBuyException;
import top.hzy520.common.util.QiniuFileUploadUtil;
import top.hzy520.feign.NotificationClient;
import top.hzy520.user.dao.UserMapper;
import top.hzy520.user.dto.ModifyPawwordInputDTO;
import top.hzy520.user.entity.RegisterInfo;
import top.hzy520.user.entity.User;
import top.hzy520.user.entity.UserElement;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @Author: HouZeYu
 * @Description:
 * @Date: Created in 22:21 2018/5/30
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private NotificationClient notificationClient;

    @Autowired
    private CuratorFramework curatorFramework;

    @Override
    public void smsRegister(RegisterInfo registerInfo) throws Exception {
        InterProcessMutex lock=null;
        try {
            lock=new InterProcessMutex(curatorFramework,Constants.USER_SMSREGISTER_DISTRIBUTE_LOCK_PATH);
            boolean retry=true;
            do {
                if (lock.acquire(3000,TimeUnit.MILLISECONDS)){
                    boolean result=notificationClient.verifyMobileCode(registerInfo.getMobile(),registerInfo.getCode());
                    if (result==false){
                        throw new YuyuBuyException("手机验证码不正确");
                    }else {
                        User user=new User();
                        user.setPassword(passwordEncoder.encode(registerInfo.getPassword()));
                        user.setMobile(registerInfo.getMobile());
                        userMapper.insertSelective(user);
                        retry=false;
                    }
                }else {
                    Thread.sleep(500);
                }
            } while (retry);
        } catch (Exception e) {
            throw e;
        }finally {
            if (null!=lock){
                try {
                    lock.release();
                    log.info(registerInfo.getMobile()+Thread.currentThread().getName()+"释放了锁");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void emailRegister(RegisterInfo registerInfo) throws Exception {
        InterProcessMutex lock=null;
        try {
            lock=new InterProcessMutex(curatorFramework,Constants.USER_EMAILREGISTER_DISTRIBUTE_LOCK_PATH);
            boolean retry=true;
            do {
                if (lock.acquire(3000,TimeUnit.MILLISECONDS)){
                   boolean result=notificationClient.verifyEmailCode(registerInfo.getEmail(),registerInfo.getCode());
                   if (result==false){
                     throw new YuyuBuyException("邮箱验证码输入不正确");
                   }else {
                         User user=new User();
                         user.setEmail(registerInfo.getEmail());
                         user.setPassword(passwordEncoder.encode(registerInfo.getPassword()));
                         userMapper.insertSelective(user);
                         retry=false;
                   }
                }else {
                    Thread.sleep(500);
                }
            }while (retry);
        }catch (Exception e){
            throw e;
        }finally {
            if (null!=lock){
                try {
                    lock.release();
                    log.info(registerInfo.getMobile()+Thread.currentThread().getName()+"释放了锁");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     *手机账号登录
     * @param user
     * @return 要存入redis的用户信息
     */
    @Override
    public UserElement mobileLogin(User user) {
        UserElement userElement=new UserElement();
        //查询用户是否存在 不存在则返回让重新输入
      User existUser=userMapper.selectUserByMobile(user.getMobile());
      if (existUser==null){
          throw new YuyuBuyException("账号或密码不正确");
      }else {
            //判断用户输入密码是否匹配 匹配则返回要存入redis的用户信息
           if (passwordEncoder.matches(user.getPassword(),existUser.getPassword())){
               userElement.setMobile(existUser.getMobile());
               userElement.setUserId(existUser.getId());
               userElement.setUuid(existUser.getUuid());
               userElement.setNickname(existUser.getNickname());
               userElement.setHeadImage(existUser.getHeadImage());
               userElement.setSex(existUser.getSex());
                       return userElement;
           }else {
               throw new YuyuBuyException("账号或密码不正确");
           }
      }
    }
      /**
      *@Author: HouZeYu
      *@Description:  邮箱账号登录
      *@Date: 15:26 2018/6/3
      */
    @Override
    public UserElement emailLogin(User user) {
        UserElement userElement=new UserElement();
        //查询用户是否存在 不存在则返回让重新输入
        User existUser=userMapper.selectUserByEmail(user.getEmail());
        if (existUser==null){
            throw new YuyuBuyException("账号或密码不正确");
        }else {
            //判断用户输入密码是否匹配 匹配则返回要存入redis的用户信息
            if (passwordEncoder.matches(user.getPassword(),existUser.getPassword())){
                userElement.setEmail(existUser.getEmail());
                userElement.setUserId(existUser.getId());
                userElement.setUuid(existUser.getUuid());
                userElement.setNickname(existUser.getNickname());
                userElement.setHeadImage(existUser.getHeadImage());
                userElement.setSex(existUser.getSex());
                return userElement;
            }else {
                throw new YuyuBuyException("账号或密码不正确");
            }
        }
    }
   /**
   *@Author: HouZeYu
   *@Description: 通过user里面传来的信息判断编辑什么信息
   *@Date: 21:27 2018/6/3
   */
    @Override
    @Transactional
    public UserElement editUserInfo(User user, UserElement userElement) {
       //通过uuid获取当前用户
        User existUser=userMapper.selectUserByUuId(userElement.getUuid());
        //判断编辑哪个信息
        if (user.getNickname()!=null){
              userElement.setNickname(user.getNickname());
              existUser.setNickname(user.getNickname());
        }
        if (user.getSex()!=null){
             userElement.setSex(user.getSex());
             existUser.setSex(user.getSex());
        }
        //修改数据库信息
        userMapper.updateByPrimaryKeySelective(existUser);
        return userElement;
    }
   /**
   *@Author: HouZeYu
   *@Description: 上传头像到七牛云 并返还给前端图片链接地址
   *@Date: 17:22 2018/6/4
   */
    @Override
    public UserElement uploadHeadImage(MultipartFile file, UserElement currentUser) throws IOException {
        //查询当前用户
        User existUser=userMapper.selectUserByUuId(currentUser.getUuid());
        //上传七牛云
       String headImgUrl=Constants.QINIU_HEAD_IMG_BUCKET_URL+"/"+QiniuFileUploadUtil.uploadHeadImg(file);
       //修改数据库头像地址
        existUser.setHeadImage(headImgUrl);
        userMapper.updateByPrimaryKey(existUser);
        //修改session中头像地址
        currentUser.setHeadImage(headImgUrl);
        return currentUser;
    }
        /**
        *@Author: HouZeYu
        *@Description: 判断旧密码正确性修改密码
        *@Date: 18:58 2018/6/4
        */
    @Override
    public void modifyPassword(ModifyPawwordInputDTO modifyPawwordInputDTO, UserElement currentUser) {
        //查询当前用户
          User existUser=userMapper.selectUserByUuId(currentUser.getUuid());
          //判断旧密码正确性
          if (passwordEncoder.matches(modifyPawwordInputDTO.getOldPassword(),existUser.getPassword())){
              //正确修改密码
              existUser.setPassword(passwordEncoder.encode(modifyPawwordInputDTO.getNewPassword()));
              userMapper.updateByPrimaryKeySelective(existUser);
          }else {
              throw new YuyuBuyException("密码不正确");
          }
    }
}
